import { message } from 'ant-design-vue';
import QRCode from 'qrcode';
import html2canvas from 'html2canvas';
import axios from 'axios';
import { RespUploadData } from './store/respTypes'

interface CheckCondition {
    format?: string[];
    size?: number; // 单位是Mb
}
type ErrorType = 'size' | 'format' | null;
type BeforeUploadCheckReturn = {
    passed: boolean;
    error: null | ErrorType;
};
export function beforeUploadCheck(file: File, condition: CheckCondition): BeforeUploadCheckReturn {
    const { format, size } = condition;
    const isValidFormat = format ? format.includes(file.type) : true;
    const isValidSize = size ? file.size / 1024 / 1024 < size : true;
    let error: ErrorType = null;
    if (!isValidFormat) {
        error = 'format';
    }
    if (!isValidSize) {
        error = 'size';
    }
    return {
        passed: isValidFormat && isValidFormat,
        error,
    };
}

export const commonUploadCheck = (file: File): boolean => {
    const result = beforeUploadCheck(file, { format: ['image/jpeg', 'image/png'], size: 1 });
    const { passed, error } = result;
    if (error === 'format') {
        message.error('上传图片只能是 JPG/PNG 格式!');
    }
    if (error === 'size') {
        message.error('上传图片大小不能超过 1Mb');
    }
    return passed;
};

export const getImageDimensions = (
    url: string | File
): Promise<{ width: number; height: number }> => {
    return new Promise<{ width: number; height: number }>((resolve, reject) => {
        const img = new Image();
        img.src = typeof url === 'string' ? url : URL.createObjectURL(url);
        img.addEventListener('load', () => {
            const { naturalWidth: width, naturalHeight: height } = img;
            resolve({ width, height });
        });
        img.addEventListener('error', () => {
            reject(new Error('There was some problem with the image.'));
        });
    });
};
export const insertAt = (arr: unknown[], index: number, newItem: unknown): unknown[] => {
    return [...arr.slice(0, index), newItem, ...arr.slice(index)];
};
export const getParentElement = (element: HTMLElement, className: string): null | HTMLElement => {
    while (element) {
        if (element.classList && element.classList.contains(className)) {
            return element;
        } else {
            element = element.parentNode as HTMLElement;
        }
    }
    return null;
};
export function timeout(ms: number):Promise<undefined> {
    return new Promise(resolve => setTimeout(resolve, ms));
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function generateQRCode(id: string, url: string, width = 100):Promise<any> {
    const ele = document.getElementById(id) as HTMLCanvasElement;
    return QRCode.toCanvas(ele, url, { width });
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function takeScreenshotAndUpload(ele: HTMLElement):Promise<any> {
    // get screenshot canvas
    const canvas = await html2canvas(ele, { width: 375, useCORS: true, scale: 1 });
    // transform canvas to blob
    const canvasBlob = await getCanvasBlob(canvas);
    if (canvasBlob) {
        // upload blob to server
        const data = await uploadFile<RespUploadData>(canvasBlob);
        return data;
    }
}

function getCanvasBlob(canvas: HTMLCanvasElement) {
    return new Promise<Blob | null>(resolve => {
        canvas.toBlob(blob => {
            resolve(blob);
        });
    });
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export async function uploadFile<R = any>(file: Blob, url = "/utils/upload-img", fileName ='screenshot.png'): Promise<any> {
    const newFile = file instanceof File ? file : new File([file], fileName)
    const formData = new FormData()
    formData.append(newFile.name, newFile)
    const { data } = await axios.post<R>(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
    return data
  }
